#ifndef EVENT_H
#define EVENT_H

#include "AReVi/arObject.h"
namespace AReVi {
	class MemoryBlock;
	class AbstractOStream;
	class AbstractIStream;
}
using namespace AReVi;

class Connector;
class Element;
class FIFO;

/** The Event class contains the data that will be broadcasted
 *  to all the clients through the connector. */
class Event : public ArObject {
public:
    AR_CLASS(Event)
    AR_CONSTRUCTOR(Event)

	friend class Connector;

    /** Defines the emitter */
    void setEmitter(ArRef<Element> emitter);
    /** Defines the emitter */
    inline void setEmitterID(const StlString & emitterID) { _emitterID = emitterID; }
    /** Retreive the emitter */
    inline StlString getEmitterID() const { return _emitterID; }

    /** Defines the type of the event */
    inline void setType(const StlString & type) { _type = type; }
    /** Retreive the type of the event */
    inline StlString getType() const { return _type; }

	/** Retreive data size */
	unsigned int getDataSize() const;
	/** Retreive data */
	inline ArRef<MemoryBlock> getData() const { return _data; }
	/** Retreive input stream to read data */
	inline ArRef<AbstractIStream> getIStream() const { return _input; }
	/** Retreive Output stream to write data */
	inline ArRef<AbstractOStream> getOStream() const { return _output; }

protected:
    /** Emitter ID can correspond to the ID of an element or be
     *  abstract like Environment, Game, ... */
    StlString _emitterID;
    /** Event type must comprehensible by the listener, 
     *  for example : NEW, UPDATE, DELETE, HIDE ...*/
    StlString _type;
	/** Event data */
	ArRef<MemoryBlock> _data;
	/** Event data accessor for reading */
	ArRef<AbstractIStream> _input;
	/** Event data accessor for writing */
	ArRef<AbstractOStream> _output;

    /** Create a memory block corresponding to the event */
    bool appendToStack(ArRef<FIFO> stack) const;
    /** Create an event from a stack */
    static ArRef<Event> createFromStack(ArRef<FIFO> stack);

};

#endif
